"""
Live2D 模型简化下载脚本
使用可靠的 CDN 源直接下载必需文件
"""

import os
import sys
import urllib.request
import urllib.error
from pathlib import Path
import json

def download_file_with_retry(url, dest_path, retries=3):
    """带重试的文件下载"""
    for attempt in range(retries):
        try:
            print(f"  [{attempt+1}/{retries}] 下载: {dest_path.name}")
            
            # 创建目标目录
            dest_path.parent.mkdir(parents=True, exist_ok=True)
            
            # 设置请求头，模拟浏览器
            headers = {
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
            }
            req = urllib.request.Request(url, headers=headers)
            
            # 下载文件
            with urllib.request.urlopen(req, timeout=30) as response:
                data = response.read()
                with open(dest_path, 'wb') as f:
                    f.write(data)
            
            file_size = len(data)
            print(f"    ✓ 成功 ({file_size:,} bytes)")
            return True
            
        except urllib.error.HTTPError as e:
            print(f"    ✗ HTTP错误 {e.code}: {e.reason}")
        except urllib.error.URLError as e:
            print(f"    ✗ 网络错误: {e.reason}")
        except Exception as e:
            print(f"    ✗ 失败: {e}")
        
        if attempt < retries - 1:
            print(f"    重试中...")
    
    return False


def create_minimal_model_config(model_dir):
    """创建最小化的模型配置文件"""
    print("\n创建占位配置文件...")
    
    config = {
        "Version": 3,
        "FileReferences": {
            "Moc": "hiyori.moc3",
            "Textures": ["textures/texture_00.png"],
            "Physics": "hiyori.physics3.json",
            "DisplayInfo": "hiyori.cdi3.json"
        },
        "Groups": [
            {
                "Target": "Parameter",
                "Name": "LipSync",
                "Ids": ["ParamMouthOpenY"]
            }
        ]
    }
    
    config_path = model_dir / "hiyori.model3.json"
    with open(config_path, 'w', encoding='utf-8') as f:
        json.dump(config, f, indent=2)
    
    print(f"  ✓ 创建: {config_path.name}")
    return True


def download_from_jsdelivr(model_dir):
    """从 jsDelivr CDN 下载（通常最稳定）"""
    print("\n=== 尝试从 jsDelivr CDN 下载 ===")
    
    # 这是一个已知可用的 Live2D 示例模型
    base_url = "https://cdn.jsdelivr.net/gh/Eikanya/Live2d-model/Live2d-model/hiyori/"
    
    files = {
        "hiyori.model.json": "hiyori.model3.json",  # 重命名
        "hiyori.moc": "hiyori.moc3",  # 重命名
        "textures/texture_00.png": "textures/texture_00.png"
    }
    
    success_count = 0
    for src_file, dest_file in files.items():
        url = base_url + src_file
        dest_path = model_dir / dest_file
        if download_file_with_retry(url, dest_path):
            success_count += 1
    
    return success_count == len(files)


def download_from_alternative_cdn(model_dir):
    """备用 CDN 源"""
    print("\n=== 尝试从备用 CDN 下载 ===")
    
    base_url = "https://fastly.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/assets/"
    
    files = {
        "hiyori_free_en.model3.json": "hiyori.model3.json",
        "hiyori_free_en.moc3": "hiyori.moc3",
        "textures/texture_00.png": "textures/texture_00.png"
    }
    
    success_count = 0
    for src_file, dest_file in files.items():
        url = base_url + src_file
        dest_path = model_dir / dest_file
        if download_file_with_retry(url, dest_path):
            success_count += 1
    
    return success_count == len(files)


def verify_model(model_dir):
    """验证模型文件"""
    print("\n验证模型文件...")
    
    required_files = [
        ("hiyori.model3.json", "或 hiyori.model.json"),
        ("hiyori.moc3", "或 hiyori.moc")
    ]
    
    all_exist = True
    found_files = []
    
    for primary, alternative in required_files:
        primary_path = model_dir / primary
        
        # 检查所有可能的文件名
        possible_paths = [
            model_dir / primary,
            model_dir / primary.replace('.model3.json', '.model.json'),
            model_dir / primary.replace('.moc3', '.moc'),
            model_dir / primary.replace('hiyori', 'hiyori_free_en')
        ]
        
        found = False
        for path in possible_paths:
            if path.exists():
                size = path.stat().st_size
                print(f"  ✓ {path.name} ({size:,} bytes)")
                found_files.append(path.name)
                found = True
                break
        
        if not found:
            print(f"  ✗ {primary} {alternative} (缺失)")
            all_exist = False
    
    # 检查纹理
    texture_paths = list(model_dir.glob("textures/*.png"))
    if texture_paths:
        for tex in texture_paths:
            size = tex.stat().st_size
            print(f"  ✓ {tex.relative_to(model_dir)} ({size:,} bytes)")
    else:
        print(f"  ⚠ 纹理文件缺失")
        all_exist = False
    
    return all_exist


def main():
    """主函数"""
    print("=" * 70)
    print("Live2D 模型简化下载工具")
    print("=" * 70)
    
    # 设置模型目录
    project_root = Path(__file__).parent
    model_dir = project_root / "models" / "hiyori"
    
    print(f"\n目标目录: {model_dir}")
    
    # 创建目录
    model_dir.mkdir(parents=True, exist_ok=True)
    
    # 尝试下载源1
    success = download_from_jsdelivr(model_dir)
    
    # 如果失败，尝试源2
    if not success:
        print("\n第一个源失败，尝试备用源...")
        success = download_from_alternative_cdn(model_dir)
    
    # 如果还是失败，创建占位配置
    if not success:
        print("\n所有下载源都失败，创建占位配置...")
        create_minimal_model_config(model_dir)
    
    # 验证结果
    if verify_model(model_dir):
        print("\n" + "=" * 70)
        print("✓ Live2D 模型文件已就绪！")
        print("=" * 70)
        print(f"\n模型位置: {model_dir}")
        print("\n下一步:")
        print("1. 运行验证脚本: python verify_live2d_model.py")
        print("2. 启动完整系统: python main.py")
    else:
        print("\n" + "=" * 70)
        print("⚠ 下载不完整")
        print("=" * 70)
        print("\n建议:")
        print("1. 检查网络连接")
        print("2. 参考 LIVE2D_DOWNLOAD_GUIDE.md 手动下载")
        print("3. 或使用简化模式: python demo_without_live2d.py --auto")
        return 1
    
    return 0


if __name__ == "__main__":
    sys.exit(main())
